home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / cpu_tp.com / CPU.ASM < prev    next >
Encoding:
Assembly Source File  |  1989-05-15  |  8.7 KB  |  278 lines

  1. ; Assembler interface to Turbo Pascal - CPU
  2. ;
  3. ; Copyright 1989 by Mark R. Boler  -  All Rights Reserved
  4.  
  5. TITLE    CPU
  6.  
  7. POPFF    macro
  8.          local   L1, L2
  9.  
  10.          jmp     short L2
  11. L1:
  12.          iret
  13.  
  14. L2:
  15.          push    cs
  16.          call    L1
  17.  
  18.          endm
  19.  
  20. CODE     SEGMENT WORD PUBLIC
  21.  
  22.          ASSUME  CS:CODE
  23.  
  24.          PUBLIC  CpuInfo
  25.  
  26. ; FUNCTION CpuInfo: WORD; EXTERNAL;
  27.  
  28. ARG_STR  STRUC
  29.  
  30.          dw  ?
  31. ARG_OFF  dw  ?
  32. ARG_SEG  dw  ?
  33. ARG_FLG  dw  ?
  34.  
  35. ARG_STR  ENDS
  36.  
  37. FLG_08    EQU    000000000B
  38. FLG_06    EQU    000000001B
  39. FLG_NEC   EQU    000000010B
  40. FLG_18    EQU    000000100B
  41. FLG_28    EQU    000000111B
  42. FLG_38    EQU    000001001B
  43. FLG_87    EQU    000010000B
  44. FLG_287   EQU    000100000B
  45. FLG_387   EQU    000110000B
  46. FLG_1167  EQU    010000000B
  47. FLG_BAD   EQU    100000000B
  48.  
  49. CpuInfo  PROC    FAR
  50.          mov     ah, 01110000B          ; set up ah for flags
  51.          push    ax                     ; put them into the flags
  52.          popf
  53.          pushf                          ; get them back into ah for testing
  54.          pop     ax
  55.          test    ah, 10000000B          ; if flags bit 15 set = 8088/86/188/186
  56.          jnz     SHORT LowCPU           ; jump if it is an 8088/86 or 80188/186
  57.          test    ah, 01110000B          ; if bits 12-14 set it is an 80286
  58.          jnz     SHORT Is386            ; jump if it is an 80386
  59.          mov     bx, FLG_28             ; set to 80286 processor
  60.          jmp     SHORT CkMathCPU        ; check for math cpu
  61. Is386:
  62.          mov     bx, FLG_38             ; set to 80386 processor
  63.          jmp     SHORT CkMathCPU        ; check for math cpu
  64. LowCPU:                                 ; determine which 801x processor
  65.          mov     al, 11111111B          ; set al to all 1's
  66.          mov     cl, 33                 ; and 8088/86 will do a 33 bit shift
  67.          shl     ax, cl                 ; an 80188/186 will only shift 1 time
  68.          jnz     SHORT Is18x            ; jump if it is an 80188/80186
  69.          mov     bx, FLG_NEC            ; assume NEC processor
  70.          call    CkNEC                  ; see if it is NEC processor
  71.          jcxz    CkPFQ                  ; it was so check pre-fetch queue
  72.          mov     bx, FLG_08             ; it is an 808x processor
  73.          jmp     SHORT CkPFQ            ; check pre-fetch queue
  74. Is18x:
  75.          mov     bx, FLG_18             ; set to 8018x processor
  76.  
  77. CkPFQ:
  78.          xor     dx, dx         ; set up max holding variable in dx
  79.          mov     cx, 8          ; set up count variable in cx
  80. CkPFQ1:
  81.          call    PFQSub         ; check the value
  82.          cmp     ax, dx         ; use the larger of the two
  83.          jbe     CkPFQ2         ; ax is smaller
  84.          mov     dx, ax         ; save for later in dx
  85. CkPFQ2:
  86.          loop    CkPFQ1         ; loop until all iterations done
  87.          cmp     dx, 4          ; Check PFQ
  88.          jbe     CkBadChip      ; Jump if xxxx8
  89.          or      bx, FLG_06     ; PFQ length is 5 or longer
  90.  
  91. CkBadChip:
  92.          call    CkChip         ; call subroutine
  93.          jcxz    CkMathCPU      ; if cx is 0 then the CPU is good
  94.          or      bx, FLG_BAD    ; it is a bad chip
  95. CkMathCPU:
  96.          call    MathCPU        ; call subroutine
  97.          mov     ax, bx         ; set return value into ax
  98.          ret                    ; return to caller
  99. CpuInfo  ENDP
  100.  
  101. CkNEC    PROC    NEAR
  102.          mov     cx, 0FFFFh     ; read max amount of bytes
  103.          sti                    ; make sure we are interrupted at least once
  104.      rep lods    BYTE PTR es:[si]  ; es and direction flag doesn't matter
  105.          ret                    ; if cx = 0 then NEC, else Intel CPU
  106. CkNEC    ENDP
  107.  
  108. PFQSub   PROC    NEAR
  109.  
  110.          ASSUME  ds:CODE, es:CODE
  111.  
  112. @REP     EQU     18             ; max length of PFQ we can handle
  113.  
  114.          push    bx             ; save bx
  115.          push    cx             ; save cx
  116.          push    dx             ; save dx
  117.          std                    ; string ops go backwards
  118.          mov     cx, @REP       ; Loop counter
  119.          mov     ax, cs         ; make es:[di] = PFQ last byte in fill area
  120.          mov     es, ax
  121.          lea     di, LAB_NOP + @REP - 1
  122.          mov     al, cs:LAB_INC ; Change to inc bx
  123.          mov     ah, cs:LAB_NOP
  124.          mov     si, 1
  125.          xor     dx, dx
  126.          cli
  127.  
  128.          EVEN
  129.          nop
  130. PFQSub_NEXT:
  131.          xor     bx, bx         ; Initialize flag
  132.          div     si
  133.          stosb                  ; Change the instruction
  134.  
  135. LAB_NOP  label   byte
  136.          rept    @REP
  137.          nop                    ;; Fill byte
  138.          endm
  139.          mov     es:[di + 1], ah      ; Restore the NOP
  140.          or      bx, bx
  141.          loopnz  PFQSub_NEXT
  142.          sti
  143.          mov     ax, cx
  144.          inc     ax
  145.          pop     dx
  146.          pop     cx
  147.          pop     bx             ; get bx back
  148.          ret                    ; return to caller
  149.  
  150. LAB_INC  label   byte
  151.          inc     bx             ; increment flag
  152. PFQSub   ENDP
  153.  
  154. CkChip   PROC    NEAR
  155.          ASSUME  ds:CODE, es:CODE
  156.  
  157.          push    bx                 ; save bx
  158.          push    ds                 ; save ds
  159.          mov     ax, 35H * 256 + 1  ; get interrupt vector 1 function
  160.          int     21H                ; call DOS
  161.          push    es
  162.          push    bx
  163.          mov     dx, OFFSET INT01
  164.          mov     ax, cs
  165.          mov     ds, ax
  166.          mov     ax, 25H * 256 + 1  ; set interrupt vector 1 function
  167.          int     21H                ; call DOS
  168.          cli                        ; turn off interrupts
  169.          mov     cx, 1              ; initialize a register
  170.          push    ss
  171.          pushf
  172.          pop     ax
  173.          or      ax, 100000000B
  174.          push    ax
  175.          POPFF
  176.  
  177.  
  178.          nop
  179. POST_NOP:
  180.          pop     ss
  181.          dec     cx
  182.  
  183.  
  184.          hlt
  185. INT01:
  186.  
  187.          push    bp
  188.          mov     bp, sp
  189.  
  190.          cmp     [bp].ARG_OFF, OFFSET cs:POST_NOP   ; check offset
  191.          pop     bp                        ; restore bp
  192.          ja      INT01_DONE
  193.  
  194.          iret                       ; return to caller
  195. INT01_DONE:
  196.  
  197. ; Restore old INT 01h handler
  198.  
  199.          pop     dx                 ; get old offset
  200.          pop     ds                 ; get old segment
  201.          mov     ax, 25H * 256 + 1  ; set interrupt vector 1 function
  202.          int     21H                ; call DOS
  203.          sti                        ; Allow interrupts again
  204.          add     sp, 3 * 2          ; Strip IP, CS, and Flags from stack
  205.          pop     ds                 ; restore ds
  206.          pop     bx                 ; restore bx
  207.          ret                        ; return to caller
  208. CkChip   ENDP
  209.  
  210. Control  EQU     WORD PTR [bp - 2]       ; control word in local stack storage
  211. ControlL EQU     BYTE PTR [bp - 2]       ; low byte of control word
  212. ControlH EQU     BYTE PTR [bp - 1]       ; high byte of control word
  213.  
  214. MathCPU  PROC    NEAR
  215.          push    bp                      ; save bp
  216.          mov     bp, sp                  ; set up stack frame
  217.          xor     ax, ax                  ; set up and init local data
  218.          FNINIT
  219.          push    ax
  220.          FNSTCW  Control
  221.          cmp     ControlH, 03H
  222.          jne     SHORT MDone
  223.          mov     al, 87
  224.          and     ControlL, 01111111B
  225.          FLDCW   Control
  226.          FDISI
  227.          FSTCW   Control
  228.          test    ControlL, 10000000B
  229.          je      SHORT Not87
  230.          or      bx, FLG_87
  231.          jmp     SHORT MDone
  232. Not87:
  233.          FINIT
  234.          FLD1
  235.          FLDZ
  236.          FDIV
  237.          FLD     ST
  238.          FCHS
  239.          FCOMPP
  240.          FSTSW   Control
  241.          FWAIT
  242.          mov     ah, ControlH
  243.          SAHF
  244.          or      bx, FLG_387
  245.          jne     SHORT MDone
  246.          or      bx, FLG_287
  247. MDone:
  248.          mov     sp, bp
  249.          pop     bp
  250.          ret                             ; return to caller
  251. MathCPU  ENDP
  252.  
  253. CkWeitek PROC    NEAR
  254.  
  255.          ASSUME  ds:CODE, es:CODE
  256.          test    bx, FLG_38      ; Are we on a 38x?
  257.          jz      CkWeitek_EXIT   ; No, thus no 1167
  258.          db      66h             ; Use EAX
  259.          push    ax              ; Save for a moment
  260.          db      66h             ; Use EAX
  261.          xor     ax, ax          ; Clear entire register
  262.          int     11h             ; Get equipment flags
  263.          db      66h             ; Use EAX
  264.          test    ax, 0000h
  265.          dw      0100h           ; Test bit 24
  266.          jz      CkWeitek_EXIT0  ; Not present
  267.          or      bx, FLG_1167    ; Mark as present
  268. CkWeitek_EXIT0:
  269.          db      66h             ; Use EAX
  270.          pop     ax              ; Restore
  271. CkWeitek_EXIT:
  272.          ret                     ; Return to caller
  273. CkWeitek ENDP
  274.  
  275. CODE     ENDS
  276.  
  277.          END
  278.